function parse(tokens) {
  var ast = {
    // ast是要生成的树，最初的根节点为root
    type: "root",
    children: [],
    indent: -1,
  };
  // 记录当前遍历路径
  let path = [ast];
  // 指针，指向上一个选择器结点
  let preNode = ast;
  // 便利到的当前结点
  let node;
  // 用来存储变量值的对象
  let vDict = {};
  while ((node = tokens.shift())) {
    // 对于变量引用，直接存储到vDict中
    if (node.type === "variableDef") {
      if (tokens[0] && tokens[0].type === "value") {
        const vNode = tokens.shift();
        vDict[node.value] = vNode.value;
      } else {
        // 如果不是变量定义，即为变量定义的值是对另一变量的引用
        preNode.rules[preNode.rules.length - 1].value = vDict[node.value];
        // 先把之前缓存变量对应的值取出，然後赋值给之前节点rules的值
      }
      continue;
    }
    // 对于属性，在指针指向的结点rules属性中添加属性
    if (node.type === "property") {
      if (node.indent > preNode.indent) {
        // 当前节点的缩进空格大於之前节点的空格，即当前节点为子节点
        preNode.rules.push({
          property: node.value,
          value: [],
        });
      } else {
        // 小於的情况，即不为子节点
        let parent = path.pop(); // 需要找出当前节点的父节点
        while (node.indent <= parent.indent) {
          parent = path.pop();
        }
        parent.rules.push({
          property: node.value,
          value: [],
        });
        preNode = parent;
        path.push(parent);
      }
      continue;
    }
    // 对于值，添加到value数组中
    if (node.type === "value") {
      try {
        preNode.rules[preNode.rules.length - 1].value.push(node.value); // 然後赋值给之前节点rules的值
      } catch (e) {
        console.error(preNode);
      }
      continue;
    }
    // 对于变量引用，直接替换成对应的值，道理与之前 'variableDef'的情况类似
    if (node.type === "variableRef") {
      preNode.rules[preNode.rules.length - 1].value.push(vDict[node.value]);
      continue;
    }
    // 对于选择器需要创建新的结点，并将指针
    if (node.type === "selector") {
      const item = {
        type: "selector",
        value: node.value,
        indent: node.indent,
        rules: [],
        children: [],
      };
      if (node.indent > preNode.indent) {
        // 当前节点的缩进空格大於之前节点的空格，即当前节点为子节点
        path[path.length - 1].indent === node.indent && path.pop(); // 缩进空格相等，即为兄弟节点
        path.push(item);
        preNode.children.push(item);
        preNode = item;
      } else {
        // 小於的情况，即不为子节点
        let parent = path.pop();
        while (node.indent <= parent.indent) {
          parent = path.pop();
        }
        parent.children.push(item);
        path.push(item);
      }
    }
  }
  return ast;
}

module.exports = {
  parse
}